package com.jack.lib.core.net

import com.jack.lib.core.ext.trues


/**
 * author : jack(黄冲)
 * e-mail : 907755845@qq.com
 * create : 2020/6/6
 * desc   :
 */

enum class NetDispatchMode{
    SINGLE,
    NORMAL,
}

enum class NetLoadingMode{
    SHOW,
    DELAY,
    HIDE,
}

sealed class NetResult<T, J: JBaseData<T>> {
    data class Success<T, J: JBaseData<T>>(var data: T?): NetResult<T, J>()
    data class Failure<T, J: JBaseData<T>>(var data: J): NetResult<T, J>()
    data class Error<T, J: JBaseData<T>>(var throwable: Throwable): NetResult<T, J>()
    class Cancel<T, J: JBaseData<T>>: NetResult<T, J>()

    fun zip(vararg result: NetResult<T, J>): ZipNetResult<T, J> {
        return ZipNetResult(arrayOf(this, *result))
    }
    fun isSuccess() = this is Success
    fun isFailure() = this is Failure
    fun isError() = this is Error
    fun isCancel() = this is Cancel

    fun allSuccess(vararg result: NetResult<*, *>, block: () -> Unit): Boolean {
        return isSuccess() && result.all { it.isSuccess() }.also { it.trues { block.invoke() } }
    }
}

data class ZipNetResult<T, J: JBaseData<*>>(private val zipData: Array<NetResult<*, J>>) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as ZipNetResult<*, *>

        if (!zipData.contentEquals(other.zipData)) return false

        return true
    }

    override fun hashCode(): Int {
        return zipData.contentHashCode()
    }

    fun allSuccess(block: (List<NetResult.Success<*, J>>) -> Unit = { }): Boolean {
        return zipData.all { it is NetResult.Success }.also { it.trues { block(this.mapSuccess()) } }
    }

    fun mapSuccess() = zipData.map { it as NetResult.Success }
}

sealed class NetCacheStrategy(var tag: String? = null) {
    class AUTO: NetCacheStrategy()
    class NOT : NetCacheStrategy()
    class TAG(tag: String?): NetCacheStrategy(tag)
}
